/*
 * dataframeiterator.cpp
 *
 *  Created on: Jul 14, 2009
 *      Author: zaca
 */

#include "dataframeiterator.h"
#include "biosignal.h"

#include <iostream>

namespace biosignal {
using namespace std;
DataFrameIterator::DataFrameIterator(const SignalSlice* signal_slice, TimePoint time) :
        m_signal_slice(signal_slice) {
//	cout << "DataFrameIterator ctor m_current_id: " << m_current_id  << " m_signal_slice: " << m_signal_slice << " this :" << this 	<< endl;
    m_current_time = time;
}

DataFrameIterator::DataFrameIterator() {
//	cout << "DataFrameIterator default ctor " << this << endl;
}

DataFrameIterator::~DataFrameIterator() {
}

DataFrameIterator::DataFrameIterator( const DataFrameIterator& other) {
//	cout << "DataFrameIterator copy ctor " << this << endl;
    m_current_time = other.m_current_time;
    m_signal_slice = other.m_signal_slice;
    m_current = other.m_current;
}

bool DataFrameIterator::operator==(const DataFrameIterator & other) const {
    //	cout << "operator== " << m_current_id 	<< endl;
    bool cond1 = !m_signal_slice->time_period().contains(m_current_time);
    bool cond2 = m_current;
    TimePeriod tp = m_signal_slice->biosignal()->dataframe_time_period(m_current_time);
    bool cond3 = tp.contains(m_current_time);
    bool cond4 = tp.contains(other.m_current_time);
/*    cout << "cur_timeperiod : " << tp << endl;
    cout << "m_current_time : " << m_current_time << endl;
    cout << "o_current_time : " << other.m_current_time << endl;*/
    return (cond2 && cond3 && cond4) || (m_current_time ==  other.m_current_time);

}
bool DataFrameIterator::operator!=(const DataFrameIterator& other) const {
    //	cout << "operator!= " << m_current_id << "  other.operator " << other.m_current_id << endl;
    bool result = !(*this==other);
    return result;

}
shared_ptr<DataFrame> DataFrameIterator::operator*() const {
//	cout << "  operator* " << endl;
//	cout << "  m_signal_slice->begin() : " << m_signal_slice->begin().current_id()  << "  m_signal_slice->end() " << m_signal_slice->end().current_id() << endl;
    update_current();
//	cout << "  m_signal_slice->begin() : " << m_signal_slice->begin().current_id()  << "  m_signal_slice->end() " << m_signal_slice->end().current_id() << endl;
    return m_current;
}
shared_ptr<DataFrame> DataFrameIterator::operator->() const {
    return *(*this);
}
DataFrameIterator& DataFrameIterator::operator++() {
//	cout << "--- start operator++  this :" << this << "  m_current_id: " << m_current_id  << " m_signal_slice: " << m_signal_slice	<< endl;
//	cout << "  m_signal_slice->begin() : " << m_signal_slice->begin().current_id()  << "  m_signal_slice->end() " << m_signal_slice->end().current_id() << endl;
    TimePeriod tp = m_signal_slice->biosignal()->dataframe_time_period( m_current_time );
//	cout << "--- end_id " << end_id << "  END : " << END << endl;
    //TODO work with a predefined undefined time offset
    if ( m_signal_slice->time_period().end()>= tp.end() ) {
        m_current_time = tp.end();
	m_current = shared_ptr<DataFrame>();
    }
//	cout << "--- operator++ " << m_current_id  << endl;
//	cout << "--- end operator++ " << m_current_id  << endl;
    return *this;
}
// DataFrameIterator& DataFrameIterator::operator--() {
//     //	cout << "--- start operator++ " << m_current_id  << endl;
//     if (m_current_id >= 0 && m_current_id < m_signal_slice->end().m_current_id
//             - 1) {
//         m_current_id--;
//     } else {
//         m_current_id = END;
//     }
//     //	cout << "--- end operator++ " << m_current_id  << endl;
//     return *this;
// }

void DataFrameIterator::update_current() const {
    if (m_signal_slice != NULL) {
//		cout << "m_current_id : " << m_current_id << "  m_signal_slice->begin() : " << m_signal_slice->begin().current_id()  << "  m_signal_slice->end() " << m_signal_slice->end().current_id() << endl;

        if (!m_current || !m_current->time_period().contains(m_current_time)) {
            const BioSignal* biosignal = m_signal_slice->biosignal();
            shared_ptr<const montage::Montage> montage = m_signal_slice->montage();
            TimePoint next_df_start = m_current_time;
            TimePoint limit_to = m_signal_slice->time_period().end();
            TimePeriod bounds(next_df_start, limit_to);
            DataFrame* bs = biosignal->create_dataframe(bounds, montage);
            m_current = shared_ptr<DataFrame> (bs);
        }
    }
}
DataFrameIterator DataFrameIterator::operator++(int) {
    //	cout << "operator++()int " << m_current_id  << endl;
    DataFrameIterator result(*this);
    ++(*this);
    return (result);

}

}
